package com.flca.pstc42.dbs;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.garret.perst.Storage;
import org.garret.perst.StorageFactory;

import com.flca.pstc42.dto.CityDto;
import com.flca.pstc42.dto.PostcodesDto;
import com.flca.pstc42.dto.StreetDto;
import com.flca.pstc42.util.PstcUtils;

public class CreatePerstDbFromCsvFiles 
{

	private static final String INDIR = "c:/temp/geocodes/";
	private static final String CITIES = "plaatsen.csv";
	private static final String STREET = "straten.csv";
	private static final String POSTCODES = "postcodes.csv";

    static final int POOL_SIZE = 32*1024*1024; // database cache size

	public static void main(String args[]) {
		CreatePerstDbFromCsvFiles creator = new CreatePerstDbFromCsvFiles();
		creator.doCreateDbs();
	}

	public void doCreateDbs() {
		open();
		testFillPlaats();
		testFillStreets();
		testFillPostcodes();
		cleanup();
	}

	private List<CityDto> cities;
	private List<StreetDto> streets;
	private List<PostcodesDto> postcodes;

	private Storage db;
	private MyRootClass root;
	
	private void open() {
		try {
			openPerstDb();
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
	}

	private void cleanup() 
	{
		try {
			db.close();
			System.out.println("done!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	
	private void testFillPlaats() 
	{
		try {
			getPlaatsenFromCsv();

			for (CityDto citydto : cities) {
				root.cityPk.put(citydto);
			}
			
			db.commit();
			cities = null;

		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
	}

	private void testFillStreets() {
		try {
			getStreetFromCsv();

			int cnt = 0;
			for (StreetDto streetdto : streets) {
				root.streetPk.put(streetdto);
				if (cnt++ % 1000 == 0) {System.out.println("cnt " + cnt);};
			}
			db.commit();

			streets = null;

		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
	}

	private void testFillPostcodes() {
		try {
			getPostcodesFromCsv();

			int cnt = 0;
			for (PostcodesDto postcodesDto : postcodes) {
				root.postcodePk.put(postcodesDto);
				root.geoLatFk.put(postcodesDto);
				root.geoLngFk.put(postcodesDto);
				if (cnt++ % 10000 == 0) {System.out.println("pc " + cnt);};
			}
			db.commit();

		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		}
	}


	private void getPlaatsenFromCsv() throws Exception {
		cities = new ArrayList<CityDto>();

		BufferedReader in = null;
		in = new BufferedReader(new InputStreamReader(new FileInputStream(INDIR
				+ CITIES)));

		String line = null;
		while ((line = in.readLine()) != null) {
			line = line.trim();
			CityDto citydto = CityDto.make(line);
			cities.add(citydto);
		}

		System.out.println("Found " + cities.size() + " cities");
	}

	private void getStreetFromCsv() throws Exception {
		streets = new ArrayList<StreetDto>();

		BufferedReader in = null;
		in = new BufferedReader(new InputStreamReader(new FileInputStream(INDIR
				+ STREET)));

		String line = null;
		while ((line = in.readLine()) != null) {
			line = line.trim();
			StreetDto dto = StreetDto.make(line);
			streets.add(dto);
		}

		System.out.println("Found " + streets.size() + " cities");
	}

	private void getPostcodesFromCsv() throws Exception {
		postcodes = new ArrayList<PostcodesDto>();

		BufferedReader in = null;
		in = new BufferedReader(new InputStreamReader(new FileInputStream(INDIR
				+ POSTCODES)));

		String line = null;
		while ((line = in.readLine()) != null) {
			line = line.trim();
			PostcodesDto dto = PostcodesDto.make(line);
			postcodes.add(dto);
		}

		System.out.println("Found " + postcodes.size() + " postcodes");
	}

	private void openPerstDb() throws Exception 
	{
        db = StorageFactory.getInstance().createStorage();
        db.open(PstcUtils.getDbsName(), POOL_SIZE);

        root = (MyRootClass)db.getRoot(); // get storage root
        if (root == null) { 
            root = new MyRootClass(db); // create root object
            db.setRoot(root); // register root object
        }
	}

	

}
